AlaskaLinuxUser's Scratchpad

Commit thy works unto the LORD, and thy thoughts shall be established. - Proverbs 16:3

Hacking with a hex editor and why I needed to cheat

20260313.jpg

After doing all that work to make the "SaveRAM" function of Gearsystem work on Ubuntu Touch, I figure I better give it a good test by playing through a game that uses it. If you are unfamiliar, my previous post is all about how I fixed the SaveRAM function so you could save the game ram to disk and have persistent games in the Gearsystem emulator. E.g., the ability to save your in game saves. So, I played through Phantasy Star to test it out.

First, while this is not a Phantasy Star review, I have to say, for a game made in the late 1980's, it is a really impressive game. It featured a top down "overworld" view while you travel from town to town. However, it had an amazing (for the time) 3D dungeon/cave/tower view which was really ahead of its time and made for some great game play. That said, this was also the TOUGHEST RPG I have EVER played. Since the dungeons are 3D in 1st person view, you had to remember every turn and way to go in each and every dungeon, and some of them were incredibly difficult mazes. One was so complicated that I eventually looked up a map just to get through it, because it had many "pitfall" traps, where the floor would collapse under your characters and drop you on some other floor, to which you don't know if it was a place you had been before or a new part of the maze. For a 4 MB cartridge, I'd say they did really well!

But, there was another reason the game was so tough, and why specifically I needed to cheat. I suppose looking up that map might be considered cheating too, I kind of figure it was more of a "time saver", but I'd accept that looking at the map was cheating too. However, what makes the game REALLY HARD is not the fact that you can get killed by just about anything, or that the mazes are so convoluded, or that you can only carry 24 items, so health restoring burgers are limited (the game designers use cola and burgers to heal you, rather than something exotic like potions). What makes the game REALLY HARD is that the game is not presented linearly, so you can go anywhere at just about any time. However, you need to talk to certain non playable characters in a linear order to advance the story line.

What that means is if you miss talking to some dude sometime and progress through the game, you can't find the thing you need or get the information you need from a different place/character. And in my case, SPOILER at the end of the game, I tried to fight what I thought was the last boss (turns out there is more game after that!) and he roasts me instantaneously to a crisp. I tried to level up more, I have the best armor available, the legendary weapons told about in lore, and I still could not beat him. After several hours (counting leveling up more) I finally gave up and read a walkthrough guide. Turns out I need a crystal from a soothsayer in a dungeon. I actually had talked to that guy, but all he did was warn me to leave now before I am destroyed.

Reading the guide, it turns out that he is supposed to ask me 5 questions. I need to know to answer these questions a certain way, and then he gives me the crystal which protects me from the big boss' death ray. But he doesn't ask me those questions! So I read back through the guide, and there is another guy in a dungeon cell locked up in a tower that I have to talk to first, who tells me the soothsayer's name. So I trekked all the way out of this dungeon, back through the lava, through the scion cave maze, through the prison back to the main town, to the star port, through the manhole cover to the village of Gothic, into my personal space ship, flew all the way to another planet, through a series of maze-like caves, back to another tower, down to it's dungeon, and talked to that guy. He told me the name of the soothsayer, and I trekked all the way back, fighting dragons, zombies, reapers, and whatnot, only to get back to the soothsayer and he still didn't ask me the right questions!

So, I read through the whole guide from the start to when I should get the crystal. Nothing mentioned that I didn't do, that I know of. I believe that the only way to solve this is to talk to every person on every planet until I find someone who mentions something about the crystal, or Lassic, or soothsayer, and then come back and he will ask me the right questions. Only the entire population of 3 planets to talk to, so that shouldn't take long, right? I tried it, gave up after an hour on the first planet.

So, I decided to cheat and just give myself the crystal instead.

I thought it would be easy because I read a guide on save state hacking[1] for this game. But it turns out, that saved state hack was for the saved state of the game with the MekaW emulator, not the actual saved backup RAM from the game. E.g., the file I get from the backup with Gearsystem is the actual saved backup RAM as if you had the original cartridge, not the save state file you get from the MekaW emulator, which is a snapshot of the running game. For instance, the guide said that at address 0547 and 0548, there would be the hex for how much money your party had, but in the savedRAM, those areas are not that, in fact those addresses are blank, but I now I have lots of money in my game, from leveling up to try to fight the last boss and nothing left to spend the money on.

I tried to read some other guides, but they were for the newer SEGA Genesis version and also didn't apply. However, I did find some DOS command line tools made specifically for this purpose, but I use Linux, so I couldn't use them without setting up Wine or something like that. However, I found a tool written in Go [2] which didn't tell me what the hex codes were, but did have this helpful line:

// A Phantasy Star 1 save file consists of five saved games.
// A header of size 0x200 exists at position 0x100 in the save file.
// Assuming saved game indexes ("GameIndex") numbered 0 through 4, each saved
// game can be found in the file at location `0x500 + 0x400 * gamenum`.
// In other words, saved games start at index 0x500 and are each of size 0x400.
// Each saved game consists of four packed 16-byte PlayerRecord structures,
// representing Alis, Myau, Odin, and Noah. At offset 0xC0 in each saved game,
// there is a 32-byte array of inventory items. At offset 0xE0 in the saved
// game, a two-byte value can be found representing the number of meseta
// followed by a one-byte value representing the number of inventory items.

Ah-ha! Now I could use the hex codes from the first[1] website with the note from the second[2] website and hack my game. If you use a hex editor like hexedit or ghex (terminal and gui, respectively), you will find that the first game save starts at 0x500, goes for 400, then the second game save starts at 0x900, goes for 400, and so on. And, a saved game looks like this:

00000500: 01cc 1c1a 5518 cc1c 6ee0 0e16 2000 0502  ....U...n... ...
00000510: 01ca 31e9 4d18 ca31 6eb6 0a14 1d00 0403  ..1.M..1n.......
00000520: 01bb 00cc 4e19 bb00 5cbd 0d17 1f00 0000  ....N...\.......
00000530: 01a8 4b8e 4516 a84b 4ab9 0418 1e00 0505  ..K.E..KJ.......
00000540: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000550: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000560: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000570: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000580: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000590: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000005a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000005b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000005c0: 3334 352d 3832 2639 2122 3b0f 2330 313e  345-82&9!";.#01>
000005d0: 2525 2525 2525 2525 0000 0000 0000 0000  %%%%%%%%........
000005e0: 423f 1800 0000 0000 0000 0000 0000 0000  B?..............
000005f0: 0300 0000 0000 0000 0000 0000 0000 0000  ................
00000600: ff01 0102 0700 01ff 0101 ff00 0000 0000  ................
00000610: 00ff 0000 0000 0000 ff00 0000 0000 0000  ................
00000620: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000630: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000640: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000650: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000660: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000670: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000680: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000690: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000006a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000006b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000006c0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000006d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000006e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000006f0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000700: ffff 00ff ffff ff00 0000 0000 0000 0000  ................
00000710: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000720: 0000 0000 ff00 0000 0000 0000 0000 0000  ................
00000730: 00ff 0000 ff00 0000 0000 0000 0000 0000  ................
00000740: ff00 00ff 0000 0000 0000 00ff 0000 0000  ................
00000750: 0000 00ff 0000 ff00 0000 0000 0000 0000  ................
00000760: 0000 00ff 00ff ffff ff00 0000 00ff 00ff  ................
00000770: ff00 ff00 0000 ffff ffff ff00 0000 0000  ................
00000780: 00ff 0000 0000 0000 0000 00ff 0000 ff00  ................
00000790: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000007a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000007b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000007c0: ffff 0000 00ff 0000 0000 00ff ff00 ff00  ................
000007d0: 0000 0000 0000 0000 ff00 0000 0000 0000  ................
000007e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000007f0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000800: 00e0 0500 0050 0100 0404 0200 de00 0000  .....P..........
00000810: 0050 01e0 0500 0d03 0000 0000 0000 0000  .P..............
00000820: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000830: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000840: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000850: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000860: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000870: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000880: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000890: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000008a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000008b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000008c0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000008d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000008e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000008f0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

Which doesn't line up with the first[1] website, but this was still really useful. I knew that I had eight burgers. And the hex code for a burger, per the second[2] website was 37. Well, searching for 37 didn't reveal anything. But per the first website was 25. Look at this line:

000005c0: 3334 352d 3832 2639 2122 3b0f 2330 313e  345-82&9!";.#01>
000005d0: 2525 2525 2525 2525 0000 0000 0000 0000  %%%%%%%%........

Wait a minute! That second line is 2525 2525 2525 2525, which is 8 burgers! Further, if each quad is two items, and you can only carry 24 items total in the game, then those two lines equal 24 items! Further study revealed that 33, 34, and 35 are the roadpass, passport, and compass, which are my first three items in my inventory!

So, how do I solve my original problem? Remember, I needed to get the crystal from the soothsayer. So, I just gave myself the crystal by changing one of the burgers (25) to be the crystal (3C). Then I just copied the saved file back to the phone, put it back in the proper folder for the emulator SaveRAM files, and when I loaded Phantasy Star, it worked! Saved game slot 1 had all my usual stuff, but the last burger was now the crystal.

By the way, that boss wasn't the final boss, and even with the crystal he is still pretty tough!

Linux - keep it simple.

[1] https://gamefaqs.gamespot.com/sms/588116-phantasy-star/faqs/24768 [2] https://github.com/mpontillo/psedit/blob/master/savefile.go